home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / bccmouse.zip / MOUSE.CPP < prev    next >
C/C++ Source or Header  |  1992-10-10  |  9KB  |  490 lines

  1. /**********************************************************************
  2.  *  
  3.  *  NAME:           mouse.cpp
  4.  *  
  5.  *  DESCRIPTION:    mouse interface
  6.  *  
  7.  *  M O D I F I C A T I O N   H I S T O R Y
  8.  *
  9.  *  when        who                 what
  10.  *  -------------------------------------------------------------------
  11.  *  12/18/90    J. Alan Eldridge    created
  12.  *  
  13.  *  NOTES:  this was created using TC++ v. 1.90 beta: 
  14.  *          "eventhandler()" will not compile correctly under TC++ 1.00
  15.  *          
  16.  *********************************************************************/
  17.  
  18. #include    <dos.h>
  19. #include    <time.h>
  20. #include    "mouse.h"
  21.  
  22. #define TRUE        1
  23. #define FALSE       0
  24. #define MOUSEINTR   0x33
  25.  
  26. static int  installed = FALSE;
  27.  
  28. static int  oldmask;
  29. void cdecl huge _saveregs   (*oldhandler)();
  30.  
  31. static int  nbuttons,
  32.             eventmask,
  33.             qsize;
  34.     
  35. #define NEVENT  8
  36.  
  37. static int  evhead = 0, evtail = 0, evcount = 0;
  38. static MouEvent mouEvent[NEVENT];
  39.  
  40. volatile int far *mou_pkbshift = (volatile int far *)MK_FP(0x40, 0x17);
  41.  
  42. static int  (*userfunc)(MouEvent&);
  43. static int  usermask;
  44.  
  45. inline int topixels(int rowcol)
  46.      { return rowcol * 8; }
  47. inline int torowcol(int pixels)
  48.     { return pixels / 8; }
  49.  
  50. int
  51. mou_exists()
  52. {
  53.     return installed;
  54. }
  55.  
  56. int
  57. mou_buttons()
  58. {
  59.     return nbuttons;
  60. }
  61.     
  62. int
  63. mou_resetmouse()
  64. {
  65.     _AX = 0;
  66.     geninterrupt(MOUSEINTR);
  67.     if (_AX)
  68.         _AX = _BX;
  69.     return _AX;
  70. }
  71.  
  72. void
  73. mou_showptr()
  74. {
  75.     _AX = 1;
  76.     geninterrupt(MOUSEINTR);
  77. }
  78.  
  79. void
  80. mou_hideptr()
  81. {
  82.     _AX = 2;
  83.     geninterrupt(MOUSEINTR);
  84. }
  85.  
  86. static int
  87. buttonstatus(int &vref, int &href)
  88. {
  89.     int buttons;
  90.  
  91.     _AX = 3;
  92.     geninterrupt(MOUSEINTR);
  93.     buttons = _BX;
  94.     vref = _DX;
  95.     href = _CX;
  96.     return buttons;
  97. }
  98.         
  99. static void
  100. setposition(int v, int h)
  101. {
  102.      _AX = 4;
  103.      _CX = h;
  104.      _DX = v;
  105.      geninterrupt(MOUSEINTR);
  106. }
  107.      
  108. static int
  109. press_release(int func, int &cntr, int &v, int &h)
  110. {
  111.     _AX = func;
  112.     geninterrupt(MOUSEINTR);
  113.     int count = _BX;
  114.     int button = _AX;
  115.     cntr = count;
  116.     v = _DX;
  117.     h = _CX;
  118.     return button;
  119. }
  120.         
  121. static int
  122. buttonpress(int &cntr, int &v, int &h)
  123. {
  124.     return press_release(0x5, cntr, v, h);
  125. }
  126.  
  127. static int
  128. buttonrelease(int &cntr, int &v, int &h)
  129. {
  130.     return press_release(0x6, cntr, v, h);
  131. }
  132.         
  133. static void
  134. setlims(int func, int minval, int maxval)
  135. {
  136.     _AX = func;
  137.     _CX = minval;
  138.     _DX = maxval;
  139.     geninterrupt(MOUSEINTR);
  140. }
  141.  
  142. static void
  143. sethlimits(int minval, int maxval)
  144. {
  145.     setlims(0x7, minval, maxval);
  146. }
  147.         
  148. static void
  149. setvlimits(int minval, int maxval)
  150. {
  151.     setlims(0x8, minval, maxval);
  152. }
  153.         
  154. static void
  155. settxtptr(int type, int arg1, int arg2)
  156. {
  157.     _AX = 0xA;
  158.     _BX = type;
  159.     _CX = arg1;
  160.     _DX = arg2;
  161.     geninterrupt(MOUSEINTR);
  162. }
  163.  
  164. void
  165. mou_setsoftptr(int andmask, int xormask)
  166. {
  167.     settxtptr(0, andmask, xormask);
  168. }
  169.  
  170. void
  171. mou_sethardptr(int start, int end)
  172. {
  173.     settxtptr(1, start, end);
  174. }    
  175.     
  176. static void
  177. _seteventhandler(int mask, int hoff, int hseg)
  178. {
  179.     _CX = mask;
  180.     _DX = hoff;
  181.     _ES = hseg;
  182.     _AX = 0xC;
  183.     geninterrupt(MOUSEINTR);
  184. }
  185.     
  186. void
  187. mou_seteventhandler(int mask, void huge cdecl _saveregs (*handler)())
  188. {
  189.     _seteventhandler(mask, FP_OFF(handler), FP_SEG(handler));
  190. }
  191.         
  192. static void
  193. setexclusionarea(int yul, int xul, int ylr, int xlr)
  194. {
  195.     _AX = 0x10;
  196.     _DX = yul;
  197.     _CX = xul;
  198.     _DI = ylr;
  199.     _SI = xlr;
  200.     geninterrupt(MOUSEINTR);
  201. }
  202.  
  203. static int
  204. _swapeventhandler(int mask, int newoff, int newseg, int &oldoff, int &oldseg)
  205. {
  206.     int off, seg, omask;
  207.     
  208.     _DX = newoff;
  209.     _ES = newseg;
  210.     _CX = mask;
  211.     _AX = 0x14;
  212.     geninterrupt(MOUSEINTR);
  213.     omask = _CX;
  214.     off = _DX;
  215.     seg = _ES;
  216.     oldoff = off;
  217.     oldseg = seg;
  218.     return omask;
  219. }
  220.             
  221. int
  222. mou_swapeventhandler(int mask, 
  223.     void cdecl huge _saveregs (*newhandler)(),
  224.     void cdecl huge _saveregs (**oldhandler)())
  225. {
  226.     int omask, off, seg;
  227.     
  228.     omask = _swapeventhandler(mask, FP_OFF(newhandler),
  229.         FP_SEG(newhandler), off, seg);
  230.     *oldhandler = (void (far *)())(MK_FP(seg, off));
  231.     return omask;
  232. }    
  233.  
  234. int
  235. mou_savestatesize()
  236. {
  237.     _AX = 0x15;
  238.     geninterrupt(MOUSEINTR);
  239.     return _BX;
  240. }
  241.  
  242. static void
  243. statemanip(int func, unsigned char far *buf)
  244. {
  245.     _DX = FP_OFF(buf);
  246.     _ES = FP_SEG(buf);
  247.     _AX = func;
  248.     geninterrupt(MOUSEINTR);
  249. }
  250.     
  251. void
  252. mou_savestate(unsigned char *buf)
  253. {
  254.     statemanip(0x16, buf);
  255. }
  256.  
  257. void
  258. mou_restorestate(unsigned char *buf)
  259. {
  260.     statemanip(0x17, buf);
  261. }
  262.  
  263. int
  264. mou_resetdriver()
  265. {
  266.     _AX = 0x21;
  267.     geninterrupt(MOUSEINTR);
  268.     if (_AX == 0xFFFF)
  269.         return _BX;
  270.     return 0;
  271. }
  272.  
  273. void interrupt
  274. (*mou_disabledriver())()
  275. {
  276.     int oldseg, oldoff;
  277.     
  278.     _AX = 0x1F;
  279.     geninterrupt(MOUSEINTR);
  280.     if (_AX == 0x1F) {
  281.         oldoff = _BX;
  282.         oldseg = _ES;
  283.     } else {
  284.         oldoff = oldseg = 0;
  285.     }
  286.     return (void interrupt (*)())(MK_FP(oldseg,oldoff));
  287. }
  288.         
  289. int
  290. mou_buttonstatus(int &v, int &h)
  291. {
  292.     int button = buttonstatus(v, h);
  293.  
  294.     v = torowcol(v);
  295.     h = torowcol(h);
  296.     return button;
  297. }
  298.  
  299. int
  300. mou_buttonpress(int &n, int &v, int &h)
  301. {
  302.     int button = buttonpress(n, v, h);
  303.  
  304.     v = torowcol(v);
  305.     h = torowcol(h);
  306.     return button;
  307. }
  308.  
  309. int
  310. mou_buttonrelease(int &n, int &v, int &h)
  311. {
  312.     int button = buttonrelease(n, v, h);
  313.  
  314.     v = torowcol(v);
  315.     h = torowcol(h);
  316.     return button;
  317. }
  318.  
  319. void
  320. mou_sethlimits(int minval, int maxval)
  321. {
  322.     sethlimits(topixels(minval), topixels(maxval+1)-1);
  323. }
  324.  
  325. void
  326. mou_setvlimits(int minval, int maxval)
  327. {
  328.     setvlimits(topixels(minval), topixels(maxval+1)-1);
  329. }
  330.  
  331. void
  332. mou_setposition(int v, int h)
  333. {
  334.     setposition(topixels(v), topixels(h));
  335. }
  336.  
  337. void
  338. mou_setexclusionarea(int yul, int xul, int ylr, int xlr)
  339. {
  340.     setexclusionarea(topixels(yul), topixels(xul),
  341.         topixels(ylr+1)-1, topixels(xlr+1)-1);
  342. }
  343.         
  344. //  this is the event function called by the mouse driver ...
  345.  
  346. //  begin_flame {
  347. //  as originally written, it would NOT compile correctly under 
  348. //  TC++ 1.00: the return address on the stack gets munged by an 
  349. //  extra instruction the compiler inserts before it starts the 
  350. //  great register pop (specifically, the contents of AX blows away 
  351. //  the saved IP, and you return to some place on the dark side 
  352. //  of the moon). the version checking code inserted here forces
  353. //  AX to the right value before coming back, thus patching the
  354. //  compiler's error. Note that TC++ 1.00 returns version 0x0295,
  355. //  while TC++ 1.90 beta returns version 0x0297 (drugs, maybe???).
  356. //  } end_flame
  357.  
  358. static void cdecl huge _saveregs
  359. eventhandler()
  360. {
  361.     int e = _AX,    b = _BX,
  362.         v = _DX,    h = _CX;
  363.  
  364. #if __TURBOC__ < 0x0297
  365.     int saveip = ((int _ss *)_BP)[10];
  366. #endif    
  367.  
  368.     if (e & usermask) {
  369.         mouEvent[evhead].kbshift = *mou_pkbshift;
  370.         mouEvent[evhead].ticks = clock();
  371.         mouEvent[evhead].event = e;
  372.         mouEvent[evhead].buttons = b;
  373.         mouEvent[evhead].vertpos = torowcol(v);
  374.         mouEvent[evhead].horzpos = torowcol(h);
  375.  
  376.         if (!userfunc || userfunc(mouEvent[evhead])) {
  377.             if (evcount < qsize) 
  378.                 evcount++;
  379.             else if (++evtail == qsize)
  380.                 evtail = 0;
  381.             if (++evhead == qsize)
  382.                 evhead = 0;
  383.         }
  384.     }
  385.  
  386. #if __TURBOC__ < 0x0297
  387.     _AX = saveip;
  388. #endif    
  389. }
  390.  
  391. class mouse {
  392. private:
  393.     int exists;
  394. public:
  395.     mouse();
  396.     ~mouse();
  397. };
  398.  
  399. static mouse    Mouse;
  400.  
  401. mouse::mouse()
  402. {
  403.     evhead = evtail = evcount = 0;
  404.     exists = (nbuttons = mou_resetmouse()) != 0;
  405.     if (exists && !installed) {
  406.         oldmask = mou_swapeventhandler(eventmask = 0, 
  407.             eventhandler, &oldhandler);
  408.         usermask = MouEvAllEvents;
  409.         userfunc = 0;
  410.         qsize = NEVENT;
  411.         installed = TRUE;
  412.         mou_setsoftptr();
  413.     }
  414. }
  415.  
  416. mouse::~mouse()
  417. {
  418.     if (installed) {
  419.         mou_seteventhandler(oldmask, oldhandler);
  420.         mou_resetmouse();
  421.         installed = FALSE;
  422.     }
  423. }
  424.         
  425. int
  426. mou_seteventmask(int newmask)
  427. {
  428.     int savemask = eventmask;
  429.  
  430.     evhead = evtail = evcount = 0;
  431.     mou_seteventhandler(eventmask = newmask, eventhandler);
  432.     return savemask;
  433. }
  434.     
  435. int
  436. mou_getevent(MouEvent &ev)
  437. {
  438.     int savecnt;
  439.     
  440.     disable();
  441.     if (savecnt = evcount) {
  442.         ev = mouEvent[evtail];
  443.         if (++evtail == qsize) evtail = 0;
  444.         evcount--;
  445.     }
  446.     enable();
  447.     return savecnt;
  448. }
  449.  
  450. void
  451. mou_flushevents()
  452. {
  453.     disable();
  454.     evhead = evtail = evcount = 0;
  455.     enable();
  456. }
  457.  
  458. void
  459. mou_setuserfunc(int (*userfunc)(MouEvent &))
  460. {
  461.     disable();
  462.     ::userfunc = userfunc;
  463.     enable();
  464. }
  465.     
  466. int
  467. mou_setusermask(int newmask)
  468. {
  469.     int savemask = usermask;
  470.  
  471.     disable();
  472.     usermask = newmask;
  473.     enable();
  474.     return savemask;
  475. }
  476.  
  477. int
  478. mou_seteventqsize(int newsize)
  479. {
  480.     int savesize = qsize;
  481.  
  482.     if (newsize < 1 || newsize > NEVENT)
  483.         newsize = NEVENT;
  484.     disable();
  485.     evhead = evtail = evcount = 0;
  486.     qsize = newsize;
  487.     enable();
  488.     return savesize;
  489. }
  490.